package com.livestocksolutions;

import java.util.Date;

import com.livestocksolutions.util.UpdateHistory;

/* -- Version History --
 *  1.0 : 07 January 2012 - Initial version.
 */

/**
* This class provides a history use for a Chemical.
* @author Adam Parr
* @version 1.0
* 
* @.modified 16 March 2013
*/
public class ChemicineHistory<T extends UsedItem> extends UsableItemHistory {
	/**
	 * The batch number of the Chemical or Medicine.
	 */
	protected String batchNumber;
	/**
	 * Date of manufacture of the Chemical or Medicine.
	 */
	protected long manufactureDate;
	/**
	 * Expiration date of the Chemical or Medicine.
	 */
	protected long expiry;
	
	/**
	 * Create a chemical/medicines usage history
	 * @param chemical the chemical/medicine to add 
	 * @param quantity amount of the chemical/medicine used
	 * @param measurement units the quantity is measured in
	 */
	protected ChemicineHistory(Chemicine<T> chemical, double quantity, String measurement) {
		super(chemical, quantity, measurement);
	}
	
	/**
	 * Create a chemical/medicines usage history
	 * @param chemical the chemical/medicine to add 
	 * @param quantity amount of the chemical/medicine used
	 * @param measurement units the quantity is measured in
	 * @param date The date this Chemical/medicine was used.
	 */
	protected ChemicineHistory(Chemicine<T> chemical, double quantity, String measurement, Date date) {
		super(chemical, quantity, measurement, date);
	}
	
	/**
	 * Get the Batch Number for this Chemical/medicine
	 * @return Batch number of this particular Chemical/medicine
	 */
	public String getBatchNumber(){
		return batchNumber;
	}
	
	/**
	 * Set the Batch Number for this Chemical/medicine.
	 * @param batchNumber The Batch number that this Chemical/medicine was apart of
	 */
	public void setBatchNumber(String batchNumber){
		if(this.batchNumber!=batchNumber){
			this.batchNumber=batchNumber;
			update.put("BATCHNO", new UpdateHistory(this.batchNumber));
		}
	}
	
	/**
	 * Get the date this Chemical/medicine was produced
	 * @return The date of this particular Chemical/medicine production
	 */
	public Date getManufactureDate(){
		return manufactureDate==0?null:new Date(manufactureDate);
	}
	
	/**
	 * Set the date of manufacture of this Chemical/medicine.
	 * @param manufactureDate The date this Chemical/medicine was produced
	 */
	public void setManufactureDate(Date manufactureDate){
		if(manufactureDate!=null&&this.manufactureDate!=manufactureDate.getTime()){
			this.manufactureDate=manufactureDate.getTime();
			update.put("MANUFACTUREDATE", new UpdateHistory(String.valueOf(this.manufactureDate)));
		}
		
	}
	
	/**
	 * Get the date this Chemical/medicine is set to expire
	 * @return The date of this Chemical/medicine is considered to be no-longer usable
	 */
	public Date getExpiryDate(){
		return expiry==0?null:new Date(expiry);
	}
	
	/**
	 * Set the date of expiration of this Chemical/medicine.
	 * @param expiryDate The date this Chemical/medicine will expire
	 */
	public void setExpiryDate(Date expiryDate){
		if(expiryDate!=null&&expiry!=expiryDate.getTime()){
			expiry=expiryDate.getTime();
			update.put("EXPIRYDATE", new UpdateHistory(String.valueOf(expiry)));
		}
	}
	
	/**
	 * Updates this Object with the updated values from the different version.
	 * @param changes ChemicineHistory that represents this Object in a different version.
	 * @return <tt>true</tt> if changes is not null and changes does not equal this object, <tt>false</tt> otherwise.
	 */
	public boolean update(ChemicineHistory<T> changes){
		if(changes!=null && this!=changes){
			super.update(changes);

			if(updateBefore("BATCHNO",changes)){
				batchNumber=changes.update.get("BATCHNO").getValue();
				update.put("BATCHNO", new UpdateHistory(batchNumber));
			}
			if(updateBefore("MANUFACTUREDATE",changes)){
				manufactureDate=Long.valueOf(changes.update.get("MANUFACTUREDATE").getValue());	
				update.put("MANUFACTUREDATE", new UpdateHistory(String.valueOf(manufactureDate)));
			}
			if(updateBefore("EXPIRYDATE",changes)){
				expiry=Long.valueOf(changes.update.get("EXPIRYDATE").getValue());
				update.put("EXPIRYDATE", new UpdateHistory(String.valueOf(expiry)));
			}
			return true;
		}
		return false;
	}
	
	/**
	 * Checks to see if the modification date of the item at this position is before the changed value
	 * @param key The String key at which to compare the modification dates of the modified objects.
	 * @param changes The ChemicineHistory that represents this ChemicineHistory on another system.
	 * @return <tt>true</tt> if the old value was modified before the changed value. <tt>false</tt> otherwise.
	 */
	protected boolean updateBefore(String key,ChemicineHistory<T> changes){
		if(this.update.get(key)==null && changes.update.get(key)!=null){
			return true;
		}else if(changes.update.get(key)==null){
			return false;
		}
		return !this.update.get(key).getDate().after(changes.update.get(key).getDate());
	}
}
